import json
import jwt
from django.db.models import Q, Max
from django.shortcuts import render
from .models import Resource, UserModel, Role, RoleResource,InterfacePromition,Exclusion,DepartmentModel,PositionModel
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import ListAPIView,CreateAPIView
from .serial import UserListSerializer,CreateUserSerializer
from tools.myjwt import mjwt
import time
from django_redis import get_redis_connection



# Create your views here.


class ResourceList(APIView):
    def get(self, request):
        # 获取所有的顶级资源
        resources = list(Resource.objects.filter(pid=None).values_list('id', "name"))
        # 将资源列表转换为字典形式
        resource_dicts = [{'id': resource[0], 'name': resource[1], 'new_list_field': []} for resource in resources]
        children_sources = Resource.objects.exclude(pid=None)
        for child in children_sources:
            data = {
                "id": child.id,
                "name": child.name,
                "url": child.url,
            }
            for parent in resource_dicts:
                if parent['id'] == child.pid.id:
                    parent["new_list_field"].append(data)

        return Response({"resource_list": resource_dicts})


class UserList(ListAPIView):
    queryset = UserModel.objects.all()
    serializer_class = UserListSerializer


class RoleList(APIView):
    def get(self, request):
        roles = list(Role.objects.values("id", "name"))
        departments = list(DepartmentModel.objects.values("id", "name"))
        positions = list(PositionModel.objects.values("id", "name"))
        return Response({"roles": roles, "departments": departments, "positions": positions})




class ParentSourceListView(APIView):
    def get(self, request):
        sources = Resource.objects.filter(pid__isnull=True)
        data = []
        for source in sources:
            data.append({
                'name': source.name,
                'id': source.id,
            })
        return Response(data)


class CreateChildSourceView(APIView):
    def post(self, request):
        pid_id = request.data.get('pid_id')
        name = request.data.get('name')
        url = request.data.get('url')
        print(pid_id, name, url)
        try:
            if pid_id == 0:
                new_source = Resource.objects.create(name=name)
            else:
                parent = Resource.objects.get(id=pid_id)
                max_promition = Resource.objects.aggregate(Max('promition'))['promition__max']
                print(max_promition)
                new_source = Resource.objects.create(name=name, pid=parent, url=url, promition=max_promition * 2)
            return Response({"msg": "创建成功", "source_id": new_source.id}, status=201)
        except Resource.DoesNotExist:
            return Response({"msg": "父级资源不存在"}, status=400)


class RoleListView(APIView):
    def get(self, request):
        roles = list(Role.objects.all().values("id", "name"))
        print(roles)
        role_list = []
        for role in roles:
            role_list.append({
                'id': role['id'],
                'name': role['name'],
            })
        return Response(role_list)


class RoleSourceListView(APIView):
    def post(self, request):
        role_id = request.data.get('role_id')
        role = Role.objects.filter(id=role_id).first()
        role_promition = role.promition
        role_pid = role.pid_id
        if role_pid is not None and role_pid != '':
            role_promition = role_promition + role.pid.promition
        # 使用promition获取所有资源
        all_resources = Resource.objects.values("id","name",'promition')
        self_resource_list = []
        for i in all_resources:
            if role_promition & i['promition'] > 0:
                self_resource_list.append(i['id'])

        all_resources_list = []
        for i in all_resources:
            all_resources_list.append({
                'key': i['id'],
                'label': i['name']
            })

        return Response({"source_list": self_resource_list, "all_list": all_resources_list})








        # role_id = request.data.get('role_id')
        # print(role_id)
        # pid = Role.objects.filter(id=role_id)
        # if len(pid) > 0:
        #     pid_id = pid.first().pid_id
        #     role_sources = RoleResource.objects.filter(role_id__in=[role_id,pid_id]).values("resource_id")
        # else:
        #     role_sources = RoleResource.objects.filter(role_id=role_id).values("resource_id")
        # role_source_list = []
        # for role_source in role_sources:
        #     role_source_list.append(role_source['resource_id'])
        #
        # total_sources = Resource.objects.all().values("id", "name")
        # total_source_list = []
        # for total_source in total_sources:
        #     total_source_list.append({
        #         'key': total_source['id'],
        #         'label': total_source['name']
        #     })
        #
        # return Response({
        #     'role_source_list': role_source_list,
        #     'total_source_list': total_source_list
        # })


class UpdateRoleSourceView(APIView):
    def post(self, request):
        role_id = request.data.get('role')
        source_list = request.data.get('list')
        role = Role.objects.filter(id=role_id).first()
        parent = role.pid
        total_sources = Resource.objects.filter(id__in=source_list).values("id",'promition')
        role_source = []
        for i in total_sources:
            if parent.promition & i['promition'] == 0:
                role_source.append(i)

        # 获取排他表
        exclusion = Exclusion.objects.filter(res1_id__in=source_list)
        exclusion_list = [i.res2_id for i in exclusion]
        exclusion_set = set(exclusion_list) & set(source_list)
        if len(exclusion_set) > 0:
            return Response({'msg': '存在排他关系',"code": 100010})

        ddata = 0
        for i in role_source:
            ddata |= i['promition']
        role.promition = ddata
        role.save()

        print(role.promition)



        # role_data = RoleResource.objects.filter(role_id=role_id)
        # role_data.delete()
        # redis_default = get_redis_connection('default')
        # redis_default.delete("res"+str(role_id))
        # for source_id in list(source_set):
        #     RoleResource.objects.create(role_id=role_id, resource_id=source_id)
        #
        # redis_default.delete("res" + str(role_id))
        return Response({'msg': '更新成功'}, status=201)




class CreateUserView(CreateAPIView):
    queryset = UserModel.objects.all()
    serializer_class = CreateUserSerializer



class LoginView(APIView):


    def post(self,request):
        phone = request.data.get('phone')
        user = UserModel.objects.filter(phone=phone).first()
        if not user:
            return Response({'msg': '用户不存在'},status=400)
        role= user.role
        prole = user.role.pid

        total_sources = Resource.objects.values("id",'name','url','pid_id','pid__name','promition',)

        resource_list = []
        total_promition = role.promition | prole.promition
        for i in total_sources:
            if total_promition & i['promition'] > 0:
                resource_list.append(i)
            elif i['promition'] == 0:
                resource_list.append(i)


        data = []
        for i in resource_list:
            data.append({"id":i['id'],"name":i['name'],"url":i['url']
                ,"pid":i['pid_id'],"pname":i['pid__name']})


        print(data)




        page_list = []
        res_dict = {}
        id_list =[]
        for i in data:
            id_list.append(i['id'])
            if i['url'] != None and i['url'] != '':
                page_list.append(i['url'])
            id = i['id']
            res_dict[id] = i
        res_list = []
        for j in data:
            pid = j['pid']
            if pid == None or pid == '':
                res_list.append(j)
            else:
                if "son" not in res_dict[pid]:
                    res_dict[pid]["son"] = []
                    res_dict[pid]["son"].append(j)
                else:
                    res_dict[pid]["son"].append(j)
        new_list = []
        for i in res_list:
            if i.get('son') != None:
                new_list.append(i)


        # #页面白名单
        # page_list = []
        # #接口白名单
        Promition = []
        # parentID_list = []
        # parent_list = []
        # inter_id_list = []
        # for i in resource_list:
        #     inter_id_list.append(i['resource_id'])
        #     page_list.append(i['resource__url'])
        #     if i['resource__pid_id'] not in parentID_list:
        #         parentID_list.append(i['resource__pid_id'])
        #         parent_list.append({
        #             'pid': i['resource__pid_id'],
        #             'pname': i['resource__pid__name'],
        #             "son": []
        #         })
        inter_list = InterfacePromition.objects.filter(resource_id__in=id_list).values('interface')

        for i in inter_list:
            Promition.append(i['interface'])
        #
        #
        # for i in resource_list:
        #     for j in parent_list:
        #         if i['resource__pid_id'] == j['pid']:
        #             j['son'].append({
        #                 'id': i['resource_id'],
        #                 'name': i['resource__name'],
        #                 'url': i['resource__url']
        #             })
        user_token = {
            'id':user.id,
            "username":user.username,
            "role_id":user.role_id,
            "exp": int(time.time()) + 60*60*3,
        }
        user_retoken = {
            'id':user.id,
            "username":user.username,
            "role_id":user.role_id,
            "exp": int(time.time()) + 60*60*24,
        }


        token = mjwt.jwt_encode(user_token)
        retoken = mjwt.jwt_encode(user_retoken)

        redis_default = get_redis_connection('default')


        Promition.append("/rbac/loginout/")
        Promition.append("/rbac/retoken/")

        redis_default.set('res'+str(role.id),json.dumps(Promition))

        # return Response({'msg': '登录成功','list': parent_list,"token":token,"retoken":retoken,"promitions":Promition,
        #                  "page_list":page_list})

        return Response({'msg': '登录成功','list': new_list,'page_list':page_list,
                         "Promition":Promition,"token":token,"retoken":retoken,})




class LoginOutView(APIView):

    def post(self,request):
        token =request.data.get('token')
        exp = int(mjwt.jwt_decode(token)['exp'])
        print(exp)

        redis_default = get_redis_connection('default')
        redis_default.setex(token,exp-int(time.time()),"1")

        return Response({'msg': '退出成功'})



class RetokenView(APIView):
    def post(self,request):
        token = request.data.get("retoken")
        exp = int(mjwt.jwt_decode(token)['exp'])
        if exp - int(time.time()) < 0:
            return Response({'msg': 'token已过期','code':"100010"})
        id = mjwt.jwt_decode(token)['id']
        username = mjwt.jwt_decode(token)['username']
        role_id = mjwt.jwt_decode(token)['role_id']
        print(id,username,role_id)
        user_token = {
            'id': id,
            "username": username,
            "role_id": role_id,
            "exp": int(time.time()) + 60 * 60 * 3,
        }
        return Response({'msg': 'token续期成功','token':mjwt.jwt_encode(user_token),'code':200})



